/**
 * QUANSHI.com Inc.
 * Copyright (c) 2016-2017 All Rights Reserved.
 */
package com.quanshi.scheduler.job.biz.route.strategy;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.concurrent.ConcurrentHashMap;

import com.quanshi.scheduler.core.base.Ret;
import com.quanshi.scheduler.core.biz.model.TriggerParam;
import com.quanshi.scheduler.job.biz.route.ExecutorRouter;
import com.quanshi.scheduler.job.dal.entity.TriggerLog;

/**
 * 最近最久未使用
 * 
 * @author yanxiang.huang 2017-07-10 13:50:43
 */
public class ExecutorRouteLRU extends ExecutorRouter
{
    private static ConcurrentHashMap<Long, LinkedHashMap<String, String>> jobLRUMap = new ConcurrentHashMap<Long, LinkedHashMap<String, String>>();
    private static long CACHE_VALID_TIME = 0;

    @Override
    public String route( long jobId, ArrayList<String> addressList )
    {
        // cache clear
        if (System.currentTimeMillis() > CACHE_VALID_TIME) {
            jobLRUMap.clear();
            CACHE_VALID_TIME = System.currentTimeMillis() + 1000 * 60 * 60 * 24;
        }

        // init lru
        LinkedHashMap<String, String> lruItem = jobLRUMap.get(jobId);
        if (lruItem == null) {
            lruItem = new LinkedHashMap<>(16, 0.75f, true);
            jobLRUMap.put(jobId, lruItem);
        }

        // put
        for (String address: addressList) {
            if (!lruItem.containsKey(address)) {
                lruItem.put(address, address);
            }
        }

        // load
        String eldestKey = lruItem.entrySet().iterator().next().getKey();
        String eldestValue = lruItem.get(eldestKey);
        return eldestValue;
    }

    @Override
    public Ret<String> routeRun( TriggerParam triggerParam, ArrayList<String> addressList, TriggerLog jobLog )
    {
        // address
        String address = route(triggerParam.getJobId(), addressList);
        jobLog.setExecutorAddress(address);

        // run executor
        Ret<String> runResult = runExecutor(triggerParam, address);
        runResult.setMsg("<br>----------------------<br>" + runResult.getMsg());

        return runResult;
    }

}
